package com.cqfae.deploycentral.app.services.impl;

import com.cqfae.deploycentral.api.utils.IdGenerator;
import com.cqfae.deploycentral.app.base.BaseConstantCode;
import com.cqfae.deploycentral.app.base.BaseConstants;
import com.cqfae.deploycentral.app.dao.entity.WindowInfo;
import com.cqfae.deploycentral.app.dao.mapper.WindowInfoMapper;
import com.cqfae.deploycentral.app.dao.mapper.WindowPlansMapper;
import com.cqfae.deploycentral.app.dao.mapper.WindowPlansTagMapper;
import com.cqfae.deploycentral.app.services.RemoteService;
import com.cqfae.deploycentral.app.services.WindowInfoService;
import com.cqfae.deploycentral.app.utils.ConvertUtil;
import com.cqfae.deploycentral.app.utils.GsonUtils;
import com.cqfae.deploycentral.app.utils.NullUtil;
import com.cqfae.deploycentral.app.web.request.WindowInfoRequest;
import com.cqfae.deploycentral.app.web.response.IPage;
import com.cqfae.deploycentral.app.web.vo.WindowInfoVo;
import com.cqfae.deploycentral.app.web.vo.WindowPlansTagVo;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.gson.reflect.TypeToken;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * Created by YANGHENG940 on 2017/7/12.
 */
@Service
@Transactional
public class WindowInfoServiceImpl implements WindowInfoService {

    @Autowired
    private IdGenerator idGenerator;

    @Autowired
    private WindowInfoMapper windowInfoMapper;

    @Autowired
    private WindowPlansMapper windowPlansMapper;

    @Autowired
    private WindowPlansTagMapper windowPlansTagMapper;

    @Autowired
    private RemoteService remoteService;


    private int closeWindowDayNum = 2;

    private String dateFormat = "yyyyMMdd";

    @Override
    public IPage<WindowInfoVo> page(WindowInfoRequest request) {
        Page<WindowInfo> page = PageHelper.startPage(request.getPageNum(), request.getPageSize());
        Example example = new Example(WindowInfo.class);
        example.setOrderByClause("window_date DESC");
        Example.Criteria ca = example.createCriteria();
        if (request.getBeginDate() > 0 || request.getEndDate() > 0) {
            Assert.isTrue((request.getBeginDate() > 0 && request.getEndDate() > 0), "日期不合法，必须有开始和结束日期");
            ca.andBetween("windowDate", request.getBeginDate(), request.getEndDate());
        }
        if (request.getLockedCode() > 0) {
            ca.andEqualTo("locked", request.getLockedCode());
        }
        windowInfoMapper.selectByExample(example);
        IPage<WindowInfoVo> ipage = ConvertUtil.pageToIpage(page, new IPage<WindowInfoVo>());
        List<WindowInfoVo> result = GsonUtils.getInstance().fromJson(GsonUtils.getInstance().toJson(page), new TypeToken<List<WindowInfoVo>>() {
        }.getType());
        for (WindowInfoVo vo : result) {
            vo.setPlansCount(windowPlansMapper.countPlans(vo.getWindowDate()));
            vo.setDeployTypeName(BaseConstants.getConstantsCodeMap().get(String.valueOf(vo.getDeployType())));
            vo.setLockedName(BaseConstants.getConstantsCodeMap().get(String.valueOf(vo.getLocked())));
        }
        ipage.setResult(result);
        return ipage;
    }

    @Override
    public List<WindowInfo> pageList(WindowInfoRequest request) {
        Page<WindowInfo> page = PageHelper.startPage(request.getPageNum(), request.getPageSize());
        Example example = new Example(WindowInfo.class);
        example.setOrderByClause("CREATE_TIME DESC");
        if (request.getWindowDate() > 0) {
            example.createCriteria().andEqualTo("windowDate", request.getWindowDate());
        }
        windowInfoMapper.selectByExample(example);
        return GsonUtils.getInstance().fromJson(GsonUtils.getInstance().toJson(page),
                new TypeToken<List<WindowInfo>>() {
                }.getType());
    }

    @Override
    public Integer save(WindowInfoVo vo) {
        WindowInfo entity = GsonUtils.getInstance().fromJson(GsonUtils.getInstance().toJson(vo), WindowInfo.class);
        entity.setId(idGenerator.nextId());
        entity.setCreateBy("123");
        entity.setCreateTime(new Date());
        return windowInfoMapper.insertSelective(entity);
    }

    @Override
    public List<WindowInfo> findAll() {
        return windowInfoMapper.selectAll();
    }

    @Override
    public WindowInfo getOne(WindowInfo entity) {
        if (NullUtil.isNotEmpty(entity.getId())) {
            return windowInfoMapper.selectOne(entity);
        }
        return null;
    }

    @Override
    public Integer createWindowForNextMonth(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH) + 1);
        int year = Integer.parseInt(DateFormatUtils.format(calendar, "yyyy"));
        int month = Integer.parseInt(DateFormatUtils.format(calendar, "MM"));
        WindowInfo windowInfo = new WindowInfo();
        windowInfo.setWindowYear(year);
        windowInfo.setWindowMonth(month);
        List<WindowInfo> wds = windowInfoMapper.select(windowInfo);
        if (NullUtil.isNotEmpty(wds) && !wds.isEmpty()) {
            return 0;
        } else {
            // 如果查询日历接口可用，就切换
            List<Date> dates = ConvertUtil.getWorkDates(year, month);
            for (Date d : dates) {
                int windowDate = Integer.parseInt(DateFormatUtils.format(d, dateFormat));
                windowInfo.setId(idGenerator.nextId());
                windowInfo.setWindowYear(year);
                windowInfo.setWindowMonth(month);
                windowInfo.setWindowDate(windowDate);
                windowInfo.setDeployType(BaseConstantCode.DEPLOY_TYPE_NORMAL);
                windowInfo.setLocked(BaseConstantCode.WINDOW_OPEN);
                windowInfo.setCreateBy("123");
                windowInfo.setCreateTime(date);
                windowInfoMapper.insert(windowInfo);
            }
            return dates.size();
        }
    }

    @Override
    public Integer closeWindowForDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH) + closeWindowDayNum);
        calendar = ConvertUtil.checkNextWorkDay(calendar);
        int tempDay = Integer.parseInt(DateFormatUtils.format(calendar, dateFormat));
        WindowInfo windowInfo = new WindowInfo();
        windowInfo.setLocked(BaseConstantCode.WINDOW_OPEN);
        windowInfo.setWindowDate(tempDay);
        windowInfo = windowInfoMapper.selectOne(windowInfo);
        if (NullUtil.isNotEmpty(windowInfo)) {
            windowInfo.setLocked(BaseConstantCode.WINDOW_CLOSE);
            windowInfo.setUpdateBy("123");
            windowInfo.setUpdateTime(date);
            return windowInfoMapper.updateByPrimaryKeySelective(windowInfo);
        }
        return 0;
    }

    @Override
    public Integer packageAppForDay(Date date) {
        Calendar calendar = Calendar.getInstance();
        int tempDay = Integer.parseInt(DateFormatUtils.format(calendar, dateFormat));
        List<WindowPlansTagVo> vos = windowPlansTagMapper.queryPlansPackageTags(tempDay);
        for (WindowPlansTagVo vo : vos) {
            remoteService.invokeJenkins(vo, BaseConstants.DEPLOY_TYPE_PACKAGE);
        }
        return 0;
    }
}
